/**
 * file name  : Jenoware/examples/JenoConverter.java
 * authors    : Xumerle Luciano
 * created    : mer 07 nov 2007 10:03:51 CET
 *
 * Copyright (c) 2004-2013 Luciano Xumerle. All rights reserved.
 *
 * This file is part of gephinfo.
 *
 * gephinfo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

import java.io.File;
import java.util.ArrayList;
// import jenoware packages
import it.ciano.jenoware.GetCSV;
import it.ciano.jenoware.Pedigree;
import it.ciano.jenoware.toPedigree;
import it.ciano.jenoware.GetARFF;
import it.ciano.jenoware.GetPHASE;
import it.ciano.jenoware.GetLINKAGE;
import it.ciano.jenoware.GetColumns;
import it.ciano.jenoware.toPedigree;
import it.ciano.jenoware.Genotype;
import it.ciano.jenoware.Phenotype;
import it.ciano.jenoware.Sbj;
import it.ciano.util.ReadPar;
import it.ciano.util.CFile;

public class JenoConverter {
    public JenoConverter() {
    }


    public static void main ( String[] args )
    throws java.io.IOException {
        ReadPar par = myPar ( args );
        par.doMsg();
        if ( !par.checkPar() || par.getParIndex ( "h" ) > -1 ) {
            par.doHelp( );
            return;
        }

        // select existing files to import
        String files[]=par.getOptionalAdditionalPars();
        ArrayList temp=new ArrayList();
        for ( int i=0; i<files.length; i++ )
            if ( ( new File ( files[i] ) ).exists() )
                temp.add ( files[i] );
        files = ( String[] ) temp.toArray ( new String[temp.size() ] );

        // creates the new Pedigree
        Pedigree ped=new Pedigree();

        /**
         * IMPORT SECTION * IMPORT SECTION * IMPORT SECTION * IMPORT SECTION *
         */

        // import csv files
        if ( par.getParIndex ( "csv" ) > -1 ) {
            for ( int i=0; i<files.length; i++ )
                toPedigree.importCSV ( ped, files[i], par.getParValue ( "csv" ) );
        }

        // import a ped file using the .dat too
        else if ( par.getParIndex ( "ped" ) > -1 ) {
            for ( int i=0; i<files.length; i++ )
                GetLINKAGE.addPEDfile ( ped, files[i], true );
        }

        // imports id;markrname;all1;all2 file format.
        else if ( par.getParIndex ( "imaa" ) > -1 ) {
            toPedigree.importID_marker_allele_allele ( ped, files, ";" );
        }

        // imports a file cointaining id and snp coded as a single value.
        // 1 is 1-1, 2 is 1-2, and 3 is 2-2
        else if ( par.getParIndex ( "img" ) > -1 ) {
            toPedigree.importID_snps ( ped, files, ";" );
        }
        // imports an ixo file
        else if ( par.getParIndex ( "ixo" ) > -1 ) {
            toPedigree.importIXO ( ped, files );
        }

        /**
         * EXPORT SECTION * EXPORT SECTION * EXPORT SECTION * EXPORT SECTION *
         */


        // output to PedPhase file
        if ( par.getParIndex ( "toPedPhase" ) > -1 ) {
            Pedigree ppp=ped.setFamilyID2Integer();
            GetCSV res=new  GetCSV ( ppp, "\t", false, true );
            CFile.saveString ( "resultsPedPhase.txt", res.toPedPhase() );
        }

        // file output as PED file (LINKAGE format)
        else if ( par.getParIndex ( "toPED" ) > -1 ) {
            GetLINKAGE pp=new GetLINKAGE ( ped );
            pp.setFilename ( "toLinkage" );
            pp.createsFile();
        }

        // file output as PED file (LINKAGE format)
        // joining alla markers as one
        else if ( par.getParIndex ( "toPEDhaplo" ) > -1 ) {
            Pedigree haplo=new Pedigree();
            toPedigree.toHaplotypeMarker ( ped, haplo, par.getParValue ( "toPEDhaplo" ), 'c' );
            GetLINKAGE pp=new GetLINKAGE ( haplo );
            pp.setFilename ( par.getParValue ( "toPEDhaplo" ) );
            pp.createsFile();
        }

        // file output as CSV file (; is separator)
        // joining alla markers as one
        else if ( par.getParIndex ( "toCSVhaplo" ) > -1 ) {
            Pedigree haplo=new Pedigree();
            toPedigree.toHaplotypeMarker ( ped, haplo, par.getParValue ( "toCSVhaplo" ), 'c' );
            Sbj[] sbjs=haplo.getListSbj();
            StringBuffer aa = new StringBuffer();
            aa.append ( "id;haplo_1;haplo_2\n" );
            for ( int i=0; i<sbjs.length; i++ ) {
                aa.append ( sbjs[i].getID() );
                aa.append ( ';' );
                aa.append ( sbjs[i].getGenotype ( par.getParValue ( "toCSVhaplo" ) ).getAll1() );
                aa.append ( ';' );
                aa.append ( sbjs[i].getGenotype ( par.getParValue ( "toCSVhaplo" ) ).getAll2() );
                aa.append ( "\n" );
            }
            CFile.saveString ( par.getParValue ( "toCSVhaplo" ) +".csv", aa.toString() );
        }

        // file output as ARFF file
        else if ( par.getParIndex ( "toArff" ) > -1 ) {
            boolean useStrings;
            if ( par.getParValue ( "toArff" ).equals ( "y" ) )
                useStrings=true;
            else useStrings=false;
            GetARFF arff= new GetARFF ( ped, useStrings );
            arff.createsFile ( "results.arff" );
        }

        // file output as PHASE files
        else if ( par.getParIndex ( "toPHASE" ) > -1 ) {
            String[] bps=par.getParValue ( "toPHASE" ).split ( "-" );
            GetPHASE phase= new GetPHASE ( ped, bps );
            phase.createsFile ();
        }

        // file output as Gerbil files
        else if ( par.getParIndex ( "toGerbil" ) > -1 ) {
            Pedigree gerbil=new Pedigree();
            toPedigree.toHaplotypeMarker ( ped, gerbil, "haplo", 'g' );
            Sbj[] sbjs=gerbil.getListSbj();
            StringBuffer aa = new StringBuffer();
            StringBuffer idorder = new StringBuffer();
            for ( int i=0; i<sbjs.length; i++ ) {
                idorder.append ( sbjs[i].getID() );
                idorder.append ( "\n" );
                aa.append ( sbjs[i].getGenotype ( "haplo" ).getAll1() );
                aa.append ( "\n" );
                aa.append ( sbjs[i].getGenotype ( "haplo" ).getAll2() );
                aa.append ( "\n" );
            }
            CFile.saveString ( "gerbil.txt", aa.toString() );
            CFile.saveString ( "gerbilIDorder.txt", idorder.toString() );
        }

        // file output as snpHAP files
        else if ( par.getParIndex ( "toSNPHAP" ) > -1 ) {
            Pedigree snphap=new Pedigree();
            toPedigree.toHaplotypeMarker ( ped, snphap, "haplo", 's' );
            Sbj[] sbjs=snphap.getListSbj();
            StringBuffer aa = new StringBuffer();
            for ( int i=0; i<sbjs.length; i++ ) {
                aa.append ( sbjs[i].getID() );
                aa.append ( "\t" );
                aa.append ( sbjs[i].getGenotype ( "haplo" ).getAll1() );
                aa.append ( "\n" );
            }
            CFile.saveString ( "snphap.txt", aa.toString() );
        }

        // file output as HIT files
        else if ( par.getParIndex ( "toHIT" ) > -1 ) {
            Pedigree hit=new Pedigree();
            toPedigree.toHaplotypeMarker ( ped, hit, "haplo", 'h' );
            Sbj[] sbjs=hit.getListSbj();
            StringBuffer aa = new StringBuffer();
            StringBuffer idorder = new StringBuffer();
            for ( int i=0; i<sbjs.length; i++ ) {
                idorder.append ( sbjs[i].getID() );
                idorder.append ( "\n" );
                aa.append ( sbjs[i].getGenotype ( "haplo" ).getAll1() );
                aa.append ( "\n" );
                aa.append ( sbjs[i].getGenotype ( "haplo" ).getAll2() );
                aa.append ( "\n" );
            }
            CFile.saveString ( "hit.txt", aa.toString() );
            CFile.saveString ( "hitIDorder.txt", idorder.toString() );
        }

        // file output as HAP files
        else if ( par.getParIndex ( "toHAP" ) > -1 ) {
            Pedigree hap=new Pedigree();
            toPedigree.toHaplotypeMarker ( ped, hap, "haplo", 'H' );
            Sbj[] sbjs=hap.getListSbj();
            StringBuffer aa = new StringBuffer();
            for ( int i=0; i<sbjs.length; i++ ) {
                aa.append ( sbjs[i].getID() );
                aa.append ( "\t" );
                aa.append ( sbjs[i].getGenotype ( "haplo" ).getAll1() );
                aa.append ( "\n" );
            }
            CFile.saveString ( "hap.txt", aa.toString() );
        }

        // file output is column
        // [id|pheno|value|date] for phenotype
        // [id|geno|all_1|all_2|date] for genotype
        else if ( par.getParIndex ( "toCOL" ) > -1 ) {
            GetColumns col= new GetColumns ( ped );
            System.out.println ( col.toString() );
        }
        // default is CSV format
        else {
            GetCSV res=new  GetCSV ( ped, ";", true, true );
            res.createsFile ( "results" );
        }
        System.err.println ( "\n=== IMPORT FINISHED ===\n" );
    }

    /**
     * Process an input args array and return the ReadPar objects.
     *
     * @param input a string array containing the parameters.
     * @return the ReadPar object.
     */
    final private static ReadPar myPar ( String[] input ) {
        ReadPar parameter = new ReadPar ( 100, "2007" );
        parameter.addSintaxHelp ( "Converter [options]" );
        parameter.addMessageInfo ( "Converter", "0.0.2", "6 nov 2007", "2007",
                                   "Luciano Xumerle <luciano.xumerle@gmail.com>" );
        parameter.addPar ( "h", "Print this help", false );
        parameter.addPar ( "ped", "Import a PED file [LINKAGE format]", false );
        parameter.addPar ( "csv", "Import a CSV file using the given separator", true );
        parameter.addPar ( "imaa", "Import a file formatted as id;markername;all1;all2", false );
        parameter.addPar ( "img", "Import a file formatted as id;snp_1;snp_2;...", false );
        parameter.addPar ( "ixo", "Import IXO file", false );
        parameter.addPar ( "toPED", "Export imported data to PED file [LINKAGE format]", false );
        parameter.addPar ( "toPEDhaplo", "Export imported data to PED file [LINKAGE format] joining all markers as one", true );
        parameter.addPar ( "toCSVhaplo", "Export imported data to CSV file [separator ';'] joining all markers as one", true );
        parameter.addPar ( "toPedPhase", "Export imported data to PedPhase file", false );
        parameter.addPar ( "toPHASE", "Export imported data to PHASE files [par: num-num-num-...]", true );
        parameter.addPar ( "toGerbil", "Export imported data to Gerbil files", false );
        parameter.addPar ( "toSNPHAP", "Export imported data to snpHAP files", false );
        parameter.addPar ( "toHAP", "Export imported data to HAP files", false );
        parameter.addPar ( "toHIT", "Export imported data to HIT files", false );
        parameter.addPar ( "toArff", "Export imported data to ARFF file. Parameter useString: [y/n]", true );
        parameter.addPar (  "toCOL", "Export imported data to column formats. [id|att|val|date]", false );
        parameter.parsePar ( input );
        return parameter;
    }

} //end class

